﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace QuadRemote
{
    class ConfigNumericTextField : TextBox
    {
        private bool isSigned;
        private bool isFloat;

        private int bits;
        private int floatDiv;

        public byte[] value;

        private double maxValue;
        private double minValue;

        public ConfigNumericTextField(bool sign, int bitsInt, int floatB)
        {
            isSigned = sign;
            bits = bitsInt + floatB;
            floatDiv = (int)Math.Pow(2,floatB);

            isFloat = (floatDiv != 1);
            value = new byte[bits / 8];

            maxValue = isSigned ? (Math.Pow(2, bits - 1) - 1) / floatDiv : (Math.Pow(2, bits) - 1) / floatDiv;

            minValue = isSigned ? -(Math.Pow(2, bits - 1)) / floatDiv : 0;

            this.KeyPress += new KeyPressEventHandler(KeyPressHandler);
            this.LostFocus += new EventHandler(TextChangedHandler);
            Text = "0";
            TextAlign = HorizontalAlignment.Right;
        }

        public void setValue(byte[] value)
        {
            //Console.WriteLine("SetValue: " + Tools.getHexString(value));
            if (value.Length != bits / 8) return;

            this.value = value;
            Int64 uv = 0;

            int i;
            for (i=0;i<value.Length;i++)
            {
                uv += (Int64)((Int64)value[i] << ((i * 8)));
            }

            if (isSigned && (value[value.Length - 1] & 0x80) == 0x80)
            {
                uv = -((Int64)Math.Pow(2, bits) - uv);
            }

            double uf = (double)uv / floatDiv;

            // smallest float val
            double floatSig = 1.0 / floatDiv;

            int sig = 0;
            while (floatSig < 10)
            {
                sig++;
                floatSig *= 10; 
            }

            uf = Math.Round(uf, sig);

            Text = uf.ToString(System.Globalization.CultureInfo.InvariantCulture);
        }

        private void TextChangedHandler(object sender, EventArgs e)
        {
            double v;
            try
            {
                v = double.Parse(Text,System.Globalization.CultureInfo.InvariantCulture);
            }
            catch (Exception ex)
            {
                v = 0;
            }
            Console.WriteLine("TextChanged: " + Text + " - " + v);

            if (v < minValue) v = minValue;
            if (v > maxValue) v = maxValue;

            Int64 iv = (Int64)(v * floatDiv);

            Int64 ivabs = iv < 0 ? -iv : iv;
            
            // -1 => 256 - 1 = 255
            if (iv < 0)
            {
                ivabs = (Int64)(Math.Pow(2, bits)) - ivabs;
            }
            byte[] b = new byte[bits / 8];

            for (int i=0;i<bits/8;i++)
            {
                b[i] = (byte)(ivabs >> (i * 8));
            }

            setValue(b);
        }

        private void KeyPressHandler(object sender, KeyPressEventArgs e)
        {
            if (!char.IsControl(e.KeyChar)
                && !char.IsDigit(e.KeyChar)
                && ((isFloat && e.KeyChar != '.') || !isFloat)
                && ((isSigned && e.KeyChar != '-') || !isSigned))
            {
                e.Handled = true;
            }

            if (isFloat)
            {
                if (e.KeyChar == '.'
                    && (sender as TextBox).Text.IndexOf('.') > -1)
                {
                    e.Handled = true;
                }
            }
        }

    }
}
